﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.IO;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.Net;
using System.Collections.Specialized;
using System.Xml.Linq;
using System.Xml;
using System.Threading;

/*
$RELEASEFILES
$RELEASENAME
$RELEASECATALOG
$DATE
$URL
$SOURCETYPE
$VCODECNAME $VCODECREV $VCODECPROFILE @ $VBITRATE
$FPS
$ALANGUAGE $AUDIOTYPE @ $ABITRATE
$RUNTIME
$ASPECT
$RESOLUTION
$SUB
$FILESIZE
$AUTHOR
$DESCRIPTION
$LANGUAGE
$FILES

$POSTER
$CASTIMG
$SCREENSHOTS
*/
namespace CHDInfoGenerator
{
    class ReleaseEnvironment
    {
        public Dictionary<string, string> Infos;
        private string pathMediaInfo;
        private string pathffmpeg;
        private XDocument LoadFromStream(Stream stream)
        {
            using (XmlReader reader = XmlReader.Create(stream))
            {
                return XDocument.Load(reader);
            }
        }
        private string GetImg(string file, int time)
        {
            XDocument x;
            NameValueCollection values;
            byte[] response;
            exeAndGetOutput(pathffmpeg, "-vframes 1 -an -ss " + time + " -i " + file + " img.jpg");
            values = new NameValueCollection
            {
                { "key", "0f74dcf52486fc0b7ec49598c4b5a571"},
                { "image", Convert.ToBase64String(File.ReadAllBytes(@"img.jpg")) }
            };
            for (; ; Thread.Sleep(30000))
            {
                try
                {
                    WebClient w = new WebClient();
                    if (String.IsNullOrEmpty(Properties.Settings.Default.ProxyServer) == false) w.Proxy = new WebProxy(Properties.Settings.Default.ProxyServer, Properties.Settings.Default.ProxyPort);
                    response = w.UploadValues("http://imgur.com/api/upload.xml", values);
                }
                catch
                {
                    continue;
                }
                x = LoadFromStream(new MemoryStream(response));
                if (x.Element("rsp") == null || x.Element("rsp").HasAttributes == false || x.Element("rsp").FirstAttribute.Value != "ok") continue;
                return "[url=" + x.Element("rsp").Element("original_image").Value + "][img]" + x.Element("rsp").Element("large_thumbnail").Value.Replace("l.jpg", "m.jpg") + "[/img][/url]";
            }
        }
        private string GetImgs(string file, int runtime, int shots)
        {
            string result = "";
            for (int i = 0; i < shots; i++)
            {
                result += GetImg(file, runtime / (shots + 1) * (i + 1));
                if (i % 2 == 1) result += "\r\n";
                else result += " ";
            }
            return result;
        }
        private string GetBiggestFile(string dir)
        {
            string biggestFile;
            biggestFile = "";
            foreach (var file in Directory.GetFiles(dir))
            {
                FileInfo oldFileInfo, newFileInfo;
                if (biggestFile == "")
                {
                    biggestFile = file;
                    continue;
                }
                oldFileInfo = new FileInfo(biggestFile);
                newFileInfo = new FileInfo(file);
                if (newFileInfo.Length > oldFileInfo.Length) biggestFile = file;
            }
            return biggestFile;
        }
        public string exeAndGetOutput(string exe, string arguments)
        {
            Process p = new Process();
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.FileName = exe;
            p.StartInfo.Arguments = arguments;
            p.Start();
            return p.StandardOutput.ReadToEnd();
        }
        public ReleaseEnvironment(string fileOrDir, int shots)
        {
            string targetFile;
            bool targetIsDir;
            Infos = new Dictionary<string, string>();
            pathMediaInfo = "MediaInfo";
            pathffmpeg = "ffmpeg";
            targetIsDir = Directory.Exists(fileOrDir);

            if (targetIsDir) targetFile = GetBiggestFile(fileOrDir);
            else targetFile = fileOrDir;

            if (targetIsDir) Infos["RELEASEFILES"] = fileOrDir.Split(new char[] { Path.DirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries).Last().Replace(' ', '.');
            else Infos["RELEASEFILES"] = Path.GetFileName(fileOrDir).Replace(' ', '.');

            if (targetIsDir) Infos["RELEASENAME"] = Infos["RELEASEFILES"];
            else Infos["RELEASENAME"] = Path.GetFileNameWithoutExtension(fileOrDir).Replace(' ', '.');

            Infos["RELEASECATALOG"] = "N/A";

            Infos["DATE"] = DateTime.Parse(exeAndGetOutput(pathMediaInfo, "--Inform=General;%Encoded_Date% " + targetFile).Replace("UTC ", "")).ToString("d");

            Infos["URL"] = "N/A";

            Infos["SOURCETYPE"] = "N/A";

            Infos["VCODECNAME"] = exeAndGetOutput(pathMediaInfo, "--Inform=Video;%Encoded_Library/Name% " + targetFile);

            Infos["VCODECREV"] = Regex.Match(exeAndGetOutput(pathMediaInfo, "--Inform=Video;%Encoded_Library/Version% " + targetFile), @"r\d+").Value;

            Infos["VCODECPROFILE"] = exeAndGetOutput(pathMediaInfo, "--Inform=Video;%Format_Profile% " + targetFile).Replace('@', ' ');

            Infos["VBITRATE"] = (Convert.ToInt32(exeAndGetOutput(pathMediaInfo, "--Inform=Video;%BitRate% " + targetFile)) / 1000).ToString() + " Kbps";

            Infos["FPS"] = exeAndGetOutput(pathMediaInfo, "--Inform=Video;%FrameRate% " + targetFile) + " fps";

            Infos["ALANGUAGE"] = "N/A";

            Infos["AUDIOTYPE"] = exeAndGetOutput(pathMediaInfo, "--Inform=Audio;%Codec% " + targetFile) + " " + exeAndGetOutput(pathMediaInfo, "--Inform=Audio;%ChannelPositions/String2% " + targetFile);

            Infos["ABITRATE"] = (Convert.ToInt32(exeAndGetOutput(pathMediaInfo, "--Inform=Audio;%BitRate% " + targetFile)) / 1000).ToString() + " Kbps";

            Infos["RUNTIME"] = exeAndGetOutput(pathMediaInfo, "--Inform=General;%Duration/String% " + targetFile);

            Infos["ASPECT"] = exeAndGetOutput(pathMediaInfo, "--Inform=Video;%DisplayAspectRatio/String% " + targetFile);

            Infos["RESOLUTION"] = exeAndGetOutput(pathMediaInfo, "--Inform=Video;%Width% " + targetFile) + "x" + exeAndGetOutput(pathMediaInfo, "--Inform=Video;%Height% " + targetFile);

            Infos["SUB"] = "N/A";

            Infos["FILESIZE"] = ((double)(new FileInfo(targetFile).Length) / 1024 / 1024 / 1024).ToString("F") + " GB";

            Infos["AUTHOR"] = "N/A";

            Infos["DESCRIPTION"] = "N/A";

            Infos["LANGUAGE"] = "N/A";

            Infos["FILES"] = fileOrDir;

            Infos["POSTER"] = "N/A";

            Infos["CASTIMG"] = "N/A";

            Infos["SCREENSHOTS"] = GetImgs(targetFile, Convert.ToInt32(exeAndGetOutput(pathMediaInfo, "--Inform=General;%Duration% " + targetFile)) / 1000, shots);
        }
        public string Parse(string data)
        {
            foreach (var info in Infos)
            {
                data = data.Replace("$" + info.Key, info.Value);
            }
            return data;
        }
    }
}
